package com.xyazm.order.domain.builder;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.xyazm.common.enums.OrderOperateTypeEnum;
import com.xyazm.common.enums.OrderStatusEnum;
import com.xyazm.common.enums.OrderTypeEnum;
import com.xyazm.common.utils.ExtJsonUtil;
import com.xyazm.market.domain.dto.CalculateOrderAmountDTO;
import com.xyazm.order.config.OrderProperties;
import com.xyazm.order.domain.entity.*;
import com.xyazm.order.domain.param.CreateOrderParam;
import com.xyazm.order.enums.*;
import com.xyazm.order.exception.OrderBizException;
import com.xyazm.order.exception.OrderErrorCodeEnum;
import com.xyazm.order.utils.OrderTypeUtils;
import com.xyazm.product.domain.dto.ProductSkuDTO;
import com.xyazm.product.enums.ProductTypeEnum;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 创建新订单的建造器
 * @author xuyou
 * @date 2022年05月02日 21:33
 */
public class NewOrderBuilder {

    /**
     * 创建订单的请求入参
    */
    private CreateOrderParam createOrderParam;

    /**
     * 商品信息列表
    */
    private List<ProductSkuDTO> productSkuDTOList;

    /**
     * 计算订单费用DTO
    */
    private CalculateOrderAmountDTO calculateOrderAmountDTO;

    /**
     * 订单超时支付时间配置信息
     */
    private OrderProperties orderProperties;

    /**
     * 全量的订单基础数据
     */
    private FullOrderData fullOrderData;

    private Map<String, ProductSkuDTO> productSkuMap;

    private Map<Integer, List<ProductSkuDTO>> productTypeMap;

    public NewOrderBuilder(CreateOrderParam createOrderParam,
                           List<ProductSkuDTO> productSkuDTOList,
                           CalculateOrderAmountDTO calculateOrderAmountDTO,
                           OrderProperties orderProperties,
                           Map<Integer, List<ProductSkuDTO>> productTypeMap) {
        this.createOrderParam = createOrderParam;
        this.productSkuDTOList = productSkuDTOList;
        this.calculateOrderAmountDTO = calculateOrderAmountDTO;
        this.orderProperties = orderProperties;
        this.fullOrderData = new FullOrderData();
        this.productTypeMap = productTypeMap;
        this.productSkuMap = productSkuDTOList.stream().collect(Collectors.toMap(ProductSkuDTO::getSkuCode, sku -> sku));
    }

    public FullOrderData build() {
        return this.fullOrderData;
    }

    /**
     * 构建OrderInfo对象(订单主表信息)
     * @return
     */
    public NewOrderBuilder buildOrderInfo() {
        OrderInfoDO orderInfoDO = new OrderInfoDO();
        // 业务线标识
        orderInfoDO.setBusinessIdentifier(createOrderParam.getBusinessIdentifier());
        // 订单Id
        orderInfoDO.setOrderId(createOrderParam.getOrderId());
        // 订单类型 : 1 一般订单
        orderInfoDO.setOrderType(OrderTypeEnum.NORMAL.getCode());
        // 订单状态 : 10 已创建
        orderInfoDO.setOrderStatus(OrderStatusEnum.CREATED.getCode());
        // 卖家id
        orderInfoDO.setSellerId(createOrderParam.getSellerId());
        // 买家id
        orderInfoDO.setUserId(createOrderParam.getUserId());
        // 使用的优惠券id
        orderInfoDO.setCouponId(createOrderParam.getCouponId());
        // 订单费用信息
        List<CreateOrderParam.OrderAmountParam> orderAmountParamList =
                createOrderParam.getOrderAmountParamList();
        // 订单费用信息转成map key:费用类型 value:费用金额
        Map<Integer, Integer> orderAmountMap = orderAmountParamList.stream()
                .collect(Collectors.toMap(
                CreateOrderParam.OrderAmountParam::getAmountType,
                CreateOrderParam.OrderAmountParam::getAmount));
        // 交易总金额 : 订单支付原价
        orderInfoDO.setTotalAmount(orderAmountMap.get(AmountTypeEnum.ORIGIN_PAY_AMOUNT.getCode()));
        // 交易支付金额 : 实付金额
        orderInfoDO.setPayAmount(orderAmountMap.get(AmountTypeEnum.REAL_PAY_AMOUNT.getCode()));

        // 订单支付信息
        List<CreateOrderParam.OrderPaymentParam> paymentRequestList =
                createOrderParam.getOrderPaymentParamList();
        if(paymentRequestList != null && !paymentRequestList.isEmpty()) {
            // 支付方式 10:微信支付 20:支付宝支付
            orderInfoDO.setPayType(paymentRequestList.get(0).getPayType());
        }

        // 用户备注
        orderInfoDO.setUserRemark(createOrderParam.getUserRemark());
        // 数据对象删除状态 0:未删除  1:已删除
        orderInfoDO.setDeleteStatus(DeleteStatusEnum.NO.getCode());
        // 订单评论状态 0:未发表评论  1:已发表评论
        orderInfoDO.setCommentStatus(DeleteStatusEnum.NO.getCode());

        long currentTimeMillis = System.currentTimeMillis();
        Integer expireTime = orderProperties.getExpireTime();
        // 支付订单截止时间 : 当前时间 + 订单超时支付时间(30分钟)
        orderInfoDO.setExpireTime(new Date(currentTimeMillis + expireTime));
        // 订单信息
        fullOrderData.setOrderInfoDO(orderInfoDO);
        return this;
    }

    /**
     * 构建OrderItem对象(订单明细信息)
     * @author xuyou
     * 2022/5/8 0008 17:11
    */
    public NewOrderBuilder buildOrderItem() {
        String orderId = createOrderParam.getOrderId();
        String sellerId = createOrderParam.getSellerId();
        List<CreateOrderParam.OrderItemParam> orderItemParamList = createOrderParam.getOrderItemParamList();

        // 促销服务计算后的订单条目费用信息
        List<CalculateOrderAmountDTO.OrderAmountDetailDTO> orderAmountDetail = calculateOrderAmountDTO.getOrderAmountDetail();

        List<OrderItemDO> orderItemDOList = new ArrayList<>();
        // 订单行明细编号
        int num = 0;
        for (ProductSkuDTO productSkuDTO : productSkuDTOList) {
            OrderItemDO orderItemDO = new OrderItemDO();
            // 订单id
            orderItemDO.setOrderId(orderId);
            // 卖家id
            orderItemDO.setSellerId(sellerId);
            // 商品明细id
            orderItemDO.setOrderItemId(this.genOrderItemId(orderId, ++num));

            // 商品id
            orderItemDO.setProductId(productSkuDTO.getProductId());
            // 商品类型 1:普通商品,2:预售商品
            orderItemDO.setProductType(productSkuDTO.getProductType());
            // 商品图片
            orderItemDO.setProductImg(productSkuDTO.getProductImg());
            // 商品名称
            orderItemDO.setProductName(productSkuDTO.getProductName());
            // 商品编码
            orderItemDO.setSkuCode(productSkuDTO.getSkuCode());
            // 商品销售单价
            orderItemDO.setSalePrice(productSkuDTO.getSalePrice());
            // 商品销售数量
            for (CreateOrderParam.OrderItemParam orderItemParam : orderItemParamList) {
                if(orderItemParam.getSkuCode().equals(productSkuDTO.getSkuCode())) {
                    orderItemDO.setSaleQuantity(orderItemParam.getSaleQuantity());
                    break;
                }
            }
            // 当前商品支付原总价 : 商品销售单价 * 商品销售数量
            orderItemDO.setOriginAmount(orderItemDO.getSalePrice() * orderItemDO.getSaleQuantity());

            // 商品实际支付金额，默认是originAmount，但是有优惠抵扣的时候需要分摊
            int realPayAmount = 0;
            // 判断该购买商品是否使用优惠折扣
            List<CalculateOrderAmountDTO.OrderAmountDetailDTO> orderAmountDetailDTOList =
                    orderAmountDetail.stream().filter(item ->
                            item.getSkuCode().equals(productSkuDTO.getSkuCode()))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(orderAmountDetailDTOList)) {
                // key: 收费类型 value: 营销系统计算出来的订单条目费用信息
                Map<Integer, CalculateOrderAmountDTO.OrderAmountDetailDTO> orderAmountDetailMap =
                        orderAmountDetailDTOList.stream().collect(Collectors.toMap
                                (CalculateOrderAmountDTO.OrderAmountDetailDTO::getAmountType, item -> item));
                // 获取优惠券抵扣金额
                CalculateOrderAmountDTO.OrderAmountDetailDTO orderAmountDetailDTO = orderAmountDetailMap.get(AmountTypeEnum.COUPON_DISCOUNT_AMOUNT.getCode());
                if(orderAmountDetailDTO != null) {
                    realPayAmount = orderItemDO.getOriginAmount() - orderAmountDetailDTO.getAmount();
                }
            }
            // 交易支付金额
            if(realPayAmount > 0) {
                orderItemDO.setPayAmount(realPayAmount);
            } else {
                orderItemDO.setPayAmount(orderItemDO.getOriginAmount());
            }

            // 商品单位
            orderItemDO.setProductUnit(productSkuDTO.getProductUnit());
            // 采购成本价
            orderItemDO.setPurchasePrice(productSkuDTO.getPurchasePrice());
            orderItemDOList.add(orderItemDO);
        }
        fullOrderData.setOrderItemDOList(orderItemDOList);
        return this;
    }

    /**
     * 生成订单明细id
     * @author xuyou
     * 2022/5/8 0008 17:16
     * @param orderId 订单id
     * @param num 行明细编号
    */
    private String genOrderItemId(String orderId,Integer num) {
        if (num < 10) {
            return orderId + "_00" + num;
        } else if (num < 100) {
            return orderId + "_0" + num;
        }
        return orderId + num;
    }


    /**
     * 构建OrderDeliveryDetail对象(订单配送信息)
     * @author xuyou
     * 2022/5/8 0008 17:37
    */
    public NewOrderBuilder buildOrderDeliveryDetail() {
        OrderDeliveryDetailDO orderDeliveryDetailDO = new OrderDeliveryDetailDO();
        // 订单id
        orderDeliveryDetailDO.setOrderId(createOrderParam.getOrderId());
        // 订单地址信息
        CreateOrderParam.OrderAddressParam orderAddressParam = createOrderParam.getOrderAddressParam();
        // 配送类型
        orderDeliveryDetailDO.setDeliveryType(orderAddressParam.getDeliveryType());
        // 配送地址信息
        orderDeliveryDetailDO.setProvince(orderAddressParam.getProvince());
        orderDeliveryDetailDO.setCity(orderAddressParam.getCity());
        orderDeliveryDetailDO.setArea(orderAddressParam.getArea());
        orderDeliveryDetailDO.setStreet(orderAddressParam.getStreet());
        orderDeliveryDetailDO.setDetailAddress(orderAddressParam.getDetailAddress());
        orderDeliveryDetailDO.setLon(orderAddressParam.getLon());
        orderDeliveryDetailDO.setLat(orderAddressParam.getLat());
        // 收货人姓名
        orderDeliveryDetailDO.setReceiverName(orderAddressParam.getReceiverName());
        // 收货人电话
        orderDeliveryDetailDO.setReceiverPhone(orderAddressParam.getReceiverPhone());
        // 调整地址次数
        orderDeliveryDetailDO.setModifyAddressCount(0);
        fullOrderData.setOrderDeliveryDetailDO(orderDeliveryDetailDO);
        return this;
    }

    /**
     * 构建OrderPaymentDetail对象(订单支付信息)
      * @author xuyou
      * 2022/5/8 0008 17:41
     */
    public NewOrderBuilder buildOrderPaymentDetail() {
        // 订单支付信息
        List<CreateOrderParam.OrderPaymentParam> orderPaymentParamList =
                createOrderParam.getOrderPaymentParamList();
        List<OrderPaymentDetailDO> orderPaymentDetailDOList = new ArrayList<>();
        for(CreateOrderParam.OrderPaymentParam paymentRequest : orderPaymentParamList) {
            OrderPaymentDetailDO orderPaymentDetailDO = new OrderPaymentDetailDO();
            // 订单id
            orderPaymentDetailDO.setOrderId(createOrderParam.getOrderId());
            // 账户类型
            orderPaymentDetailDO.setAccountType(paymentRequest.getAccountType());
            // 支付类型 10:微信支付,20:支付宝支付
            orderPaymentDetailDO.setPayType(paymentRequest.getPayType());
            // 支付状态 10:未支付,20:已支付
            orderPaymentDetailDO.setPayStatus(PayStatusEnum.UNPAID.getCode());
            // 实付金额
            orderPaymentDetailDO.setPayAmount(paymentRequest.getPayAmount());
            orderPaymentDetailDOList.add(orderPaymentDetailDO);
        }
        fullOrderData.setOrderPaymentDetailDOList(orderPaymentDetailDOList);
        return this;
    }


    /**
     * 构建OrderAmount对象(订单费用信息)
     * @author xuyou
     * 2022/5/8 0008 17:51
    */
    public NewOrderBuilder buildOrderAmount() {
        // 营销系统计算出来的费用信息
        List<CalculateOrderAmountDTO.OrderAmountDTO> orderAmountDTOList =
                calculateOrderAmountDTO.getOrderAmountList();

        List<OrderAmountDO> orderAmountDOList = new ArrayList<>();
        for(CalculateOrderAmountDTO.OrderAmountDTO orderAmountDTO : orderAmountDTOList) {
            OrderAmountDO orderAmountDO = new OrderAmountDO();
            // 订单id
            orderAmountDO.setOrderId(createOrderParam.getOrderId());
            // 费用类型
            orderAmountDO.setAmountType(orderAmountDTO.getAmountType());
            // 费用金额
            orderAmountDO.setAmount(orderAmountDTO.getAmount());
            orderAmountDOList.add(orderAmountDO);
        }
        fullOrderData.setOrderAmountDOList(orderAmountDOList);
        return this;
    }

    /**
     * 构建OrderAmountDetail对象(订单费用明细)
     * @author xuyou
     * 2022/5/8 0008 17:54
    */
    public NewOrderBuilder buildOrderAmountDetail() {

        List<OrderItemDO> orderItemDOList = fullOrderData.getOrderItemDOList();
        if (CollectionUtils.isEmpty(orderItemDOList)) {
            throw new OrderBizException(OrderErrorCodeEnum.ORDER_AMOUNT_DETAIL_BUILD_ERROR);
        }

        // 营销系统计算出来的费用明细信息
        List<CalculateOrderAmountDTO.OrderAmountDetailDTO> orderAmountDetailDTOList =
                calculateOrderAmountDTO.getOrderAmountDetail();

        List<OrderAmountDetailDO> orderAmountDetailDOList = new ArrayList<>();
        for(CalculateOrderAmountDTO.OrderAmountDetailDTO orderAmountDetailDTO : orderAmountDetailDTOList) {
            OrderAmountDetailDO orderAmountDetailDO = new OrderAmountDetailDO();
            //
            for(OrderItemDO orderItemDO : orderItemDOList) {
                if(orderItemDO.getSkuCode().equals(orderAmountDetailDTO.getSkuCode())) {
                    // 订单明细编号
                    orderAmountDetailDO.setOrderItemId(orderItemDO.getOrderItemId());
                    // 商品编号
                    orderAmountDetailDO.setProductId(orderItemDO.getProductId());
                }
            }
            // 订单id
            orderAmountDetailDO.setOrderId(createOrderParam.getOrderId());
            // 产品类型
            orderAmountDetailDO.setProductType(orderAmountDetailDTO.getProductType());
            // sku编码
            orderAmountDetailDO.setSkuCode(orderAmountDetailDTO.getSkuCode());
            // 销售数量
            orderAmountDetailDO.setSaleQuantity(orderAmountDetailDTO.getSaleQuantity());
            // 销售单价
            orderAmountDetailDO.setSalePrice(orderAmountDetailDTO.getSalePrice());
            // 收费类型
            orderAmountDetailDO.setAmountType(orderAmountDetailDTO.getAmountType());
            // 收费金额
            orderAmountDetailDO.setAmount(orderAmountDetailDTO.getAmount());
            orderAmountDetailDOList.add(orderAmountDetailDO);
        }
        fullOrderData.setOrderAmountDetailDOList(orderAmountDetailDOList);
        return this;
    }


    /**
     * 构建OperateLog对象(订单操作日志)
     * @author xuyou
     * 2022/5/8 0008 18:06
     */
    public NewOrderBuilder buildOperateLog() {
        OrderOperateLogDO orderOperateLogDO = new OrderOperateLogDO();
        orderOperateLogDO.setOrderId(createOrderParam.getOrderId());
        // 操作类型
        orderOperateLogDO.setOperateType(OrderOperateTypeEnum.NEW_ORDER.getCode());
        // 前置状态
        orderOperateLogDO.setPreStatus(OrderStatusEnum.NULL.getCode());
        // 当前状态
        orderOperateLogDO.setCurrentStatus(OrderStatusEnum.CREATED.getCode());
        fullOrderData.setOrderOperateLogDO(orderOperateLogDO);
        return this;
    }


    /**
     * 构建OrderSnapshot对象(订单快照)
     * @author xuyou
     * 2022/5/8 0008 18:08
    */
    public NewOrderBuilder buildOrderSnapshot() {
        String orderId = createOrderParam.getOrderId();
        String couponId = createOrderParam.getCouponId();
        List<OrderSnapshotDO> orderSnapshotDOList = new ArrayList<>();
        // 优惠券信息
        if(StringUtils.isNotEmpty(couponId)) {
            OrderSnapshotDO orderCouponSnapshotDO = new OrderSnapshotDO();
            orderCouponSnapshotDO.setOrderId(orderId);
            orderCouponSnapshotDO.setSnapshotType(SnapshotTypeEnum.ORDER_COUPON.getCode());
            orderSnapshotDOList.add(orderCouponSnapshotDO);
        }

        // 费用信息
        OrderSnapshotDO orderAmountSnapshotDO = new OrderSnapshotDO();
        orderAmountSnapshotDO.setOrderId(orderId);
        orderAmountSnapshotDO.setSnapshotType(SnapshotTypeEnum.ORDER_AMOUNT.getCode());
        orderSnapshotDOList.add(orderAmountSnapshotDO);

        // 订单明细信息
        OrderSnapshotDO orderItemSnapshotDO = new OrderSnapshotDO();
        orderItemSnapshotDO.setOrderId(orderId);
        orderItemSnapshotDO.setSnapshotType(SnapshotTypeEnum.ORDER_ITEM.getCode());
        orderSnapshotDOList.add(orderItemSnapshotDO);

        fullOrderData.setOrderSnapshotDOList(orderSnapshotDOList);
        return this;
    }



    /**
     * 设置订单类型
     * @return
     */
    public NewOrderBuilder setOrderType() {
        //不需要拆单
        if (productTypeMap.keySet().size() <= 1) {
            Integer productType = productSkuDTOList.get(0).getProductType();
            OrderTypeUtils.getOrderType(productType, fullOrderData.getOrderInfoDO());
        }
        return this;
    }


    /**
     * 将预售商品信息添加至orderItem的extJson里面
     * @return
     */
    public NewOrderBuilder addPreSaleInfoToOrderItems() {
        for (OrderItemDO item : fullOrderData.getOrderItemDOList()) {
            if (ProductTypeEnum.PRE_SALE.getCode().equals(item.getProductType())) {
                ProductSkuDTO productSku = productSkuMap.get(item.getSkuCode());
                //将预售商品信息放入orderItem的extJson里面
                item.setExtJson(ExtJsonUtil.mergeExtJson(item.getExtJson(), JSONObject.toJSONString(productSku.getPreSaleInfo())));
            }
        }
        return this;
    }

}
